package ${package}.api.common.model;

import lombok.Data;

import java.io.Serializable;

/**
 * 通用返回RemoteResult封装
 * data:业务正常返回的消息体,不可复用
 * status:服务状态码，为int类型， 1 为成功，0为业务异常，-1为服务异常（sql语句异常等）。
 * msg:描述信息。用于返回业务异常信息和服务异常信息，不可用于设置日志堆栈信息，和code取其一设值即可。举例：业务信息： msg="订单创建失败".
 * success:状态码为1是true,否则false
 *
 * @author weidong.lin
 * @date 2021/7/9 11:27
 */
@Data
public class RemoteResult<T> implements Serializable {
    private static final long serialVersionUID = -1;
    /**
     * 参数错误的返回码
     */
    public static final Integer CODE_PARAM_ERROR = 4;

    /**
     * 状态码
     */
    private int status;

    /**
     * 是否成功
     */
    private boolean success;

    /**
     * 消息
     */
    private String msg;

    /**
     * 编码
     */
    private Integer code;

    /**
     * 数据
     */
    private T data;

    public RemoteResult() {
    }

    public RemoteResult(int status, boolean success, int code, String msg, T data) {
        this.status = status;
        this.success = success;
        this.code = code;
        this.msg = msg;
        this.data = data;
    }

    /**
     * 请求成功
     *
     * @return {@link RemoteResult<T>}
     */
    public static <T> RemoteResult<T> success() {
        return success(null);
    }

    /**
     * 请求成功
     *
     * @param data
     * @param <T>
     * @return
     */
    public static <T> RemoteResult<T> success(T data) {
        return success(RemoteResultEnum.STATUS_SUCCESS.getMsg(), data);
    }

    /**
     * 请求成功
     *
     * @param msg
     * @param data
     * @return
     */
    public static <T> RemoteResult<T> success(String msg, T data) {
        return new RemoteResult<>(RemoteResultEnum.STATUS_SUCCESS.getStatus(), Boolean.TRUE, RemoteResultEnum.STATUS_SUCCESS.getCode(), msg, data);
    }

    /**
     * 请求失败
     *
     * @return {@link RemoteResult<T>}
     */
    public static <T> RemoteResult<T> failure() {
        return failure(RemoteResultEnum.STATUS_FAILURE.getMsg());
    }

    /**
     * 请求失败
     *
     * @param msg
     * @return {@link RemoteResult<T>}
     */
    public static <T> RemoteResult<T> failure(String msg) {
        return failure(RemoteResultEnum.STATUS_FAILURE.getCode(), msg, null);
    }

    /**
     * 请求失败
     *
     * @param code
     * @param msg
     * @return {@link RemoteResult<T>}
     */
    public static <T> RemoteResult<T> failure(int code, String msg) {
        return failure(code, msg, null);
    }

    /**
     * 失败，带消息，带数据
     *
     * @param data
     * @param <T>
     * @return
     */
    public static <T> RemoteResult<T> failure(String msg, T data) {
        return failure(RemoteResultEnum.STATUS_FAILURE.getCode(), msg, data);
    }

    /**
     * 请求失败
     *
     * @param code
     * @param msg
     * @param data
     * @return {@link RemoteResult<T>}
     */
    public static <T> RemoteResult<T> failure(int code, String msg, T data) {
        return new RemoteResult<>(RemoteResultEnum.STATUS_FAILURE.getStatus(), Boolean.FALSE, code, msg, data);
    }

    /**
     * 请求错误
     *
     * @return {@link RemoteResult<T>}
     */
    public static <T> RemoteResult<T> error() {
        return error(RemoteResultEnum.STATUS_ERROR.getMsg());
    }

    /**
     * 请求错误
     *
     * @param msg
     * @return {@link RemoteResult<T>}
     */
    public static <T> RemoteResult<T> error(String msg) {
        return error(RemoteResultEnum.STATUS_ERROR.getCode(), msg);
    }

    /**
     * 请求错误
     *
     * @param msg
     * @param data
     * @return {@link RemoteResult<T>}
     */
    public static <T> RemoteResult<T> error(String msg, T data) {
        return error(RemoteResultEnum.STATUS_ERROR.getCode(), msg, data);
    }

    /**
     * 请求错误
     *
     * @param code
     * @param msg
     * @return {@link RemoteResult<T>}
     */
    public static <T> RemoteResult<T> error(int code, String msg) {
        return error(code, msg, null);
    }

    /**
     * 请求错误
     *
     * @param code
     * @param msg
     * @param data
     * @return {@link RemoteResult<T>}
     */
    public static <T> RemoteResult<T> error(int code, String msg, T data) {
        return new RemoteResult<>(RemoteResultEnum.STATUS_ERROR.getCode(), Boolean.FALSE, code, msg, data);
    }

    @Override
    public String toString() {
        return "RemoteResult{" +
                "status=" + status +
                ", success=" + success +
                ", msg='" + msg + '\'' +
                ", code=" + code +
                ", data=" + data +
                '}';
    }

    public enum RemoteResultEnum {
        /**
         * 操作成功
         */
        STATUS_SUCCESS(1, 200, "success"),
        /**
         * 操作失败
         */
        STATUS_FAILURE(0, 201, "failure"),
        /**
         * 操作错误
         */
        STATUS_ERROR(-1, 202, "error");

        private final int status;
        private final int code;
        private final String msg;

        RemoteResultEnum(final int status, final int code, final String msg) {
            this.status = status;
            this.code = code;
            this.msg = msg;
        }

        public int getStatus() {
            return status;
        }

        public int getCode() {
            return this.code;
        }

        public String getMsg() {
            return this.msg;
        }
    }

}
